package org.aceor.mddal.atom;

import com.google.common.base.Strings;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

/**
 * 对当前datasource封装,可以侦测ds的情况,如是否挂掉
 * Created by lxue on 16/3/27.
 */
public class AtomDataSourceWrapper implements DataSource {
    private DataSource targetDs;

    public AtomDataSourceWrapper(DataSource targetDs) {
        this.targetDs = targetDs;
    }

    @Override
    public Connection getConnection() throws SQLException {
        return getConnectionFromTargetDs(null, null);
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return getConnectionFromTargetDs(username, password);
    }

    private Connection getConnectionFromTargetDs(String username, String password) throws SQLException {
        try {
            Connection connection = getConnectionFromTargetDs0(username, password);
            //TODO 进行ds可用性判断
            return connection;
        } catch (SQLException e) {
            // log
            throw e;
        }
    }

    private Connection getConnectionFromTargetDs0(String username, String password) throws SQLException {
        if (Strings.isNullOrEmpty(username) && Strings.isNullOrEmpty(password)) {
            return new AtomConnectionWrapper(targetDs.getConnection(), this);
        } else {
            return new AtomConnectionWrapper(targetDs.getConnection(username, password), this);
        }
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return targetDs.getLogWriter();
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
        targetDs.setLogWriter(out);
    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
        targetDs.setLoginTimeout(seconds);
    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return targetDs.getLoginTimeout();
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return targetDs.getParentLogger();
    }

    public <T> T unwrap(Class<T> iface) throws SQLException {
        if (isWrapperFor(iface)) {
            return (T) this;
        } else {
            throw new SQLException("not a wrapper for " + iface);
        }
    }

    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return AtomDataSourceWrapper.class.isAssignableFrom(iface);
    }

    public DataSource getTargetDs() {
        return targetDs;
    }
}
